﻿using System;
using System.Collections.Generic;
using System.Text;

public class Car : Vehicle
{
    private const int m_NumOfWheels = 4;
    private const string k_SetColor = "Please enter the color of the car (1. Yellow, 2. Red, 3. Silver, 4. White):";
    private const string k_SetNumOfDoors = "Please enter the number of doors of the car (2 / 3 / 4 / 5):";

    public enum eColor
    {
        Yellow = 1,
        Red,
        Silver,
        White
    }

    public enum eNumOfDoors
    {
        Two = 2,
        Three,
        Four,
        Five
    }

    private enum eVehiclePropertyIndex
    {
        EngineType = 0,
        ModelName,
        WheelManufacturer,
        Color,
        NumOfDoors
    }

    private eColor? m_Color = null;

    public eColor? Color
    {
        get { return m_Color; }
        set { m_Color = value; }
    }

    private eNumOfDoors? m_NumOfDoors = null;

    public eNumOfDoors? NumOfDoors
    {
        get { return m_NumOfDoors; }
        set { m_NumOfDoors = value; }
    }

    public Car()
    {
        this.AllocateVehicleProperties();
    }

    public new virtual string ToString()
    {
        string ResultStr = base.ToString();
        string[] PropertiesStrArray = new string[] { "Color: ", m_Color.ToString(), System.Environment.NewLine, "Number of doors: ", m_NumOfDoors.ToString(), System.Environment.NewLine };

        ResultStr = string.Concat(ResultStr, PropertiesStrArray);
        return ResultStr;
    }

    protected override void AllocateVehicleProperties()
    {
        base.AllocateVehicleProperties();

        m_NumOfProperties = 5;

        m_VehicleProperties.Add(new VehicleProperty(k_SetColor, 3, m_Color));
        m_VehicleProperties.Add(new VehicleProperty(k_SetNumOfDoors, 4, m_NumOfDoors));
    }

    public override void SetVehicleProperty(VehicleProperty i_VehiclePropertyToSet)
    {
        eVehiclePropertyIndex VehiclePropertyToSetIndex = (eVehiclePropertyIndex)i_VehiclePropertyToSet.VehiclePropertyIndex.Value;
        object VehiclePropertyValue = i_VehiclePropertyToSet.VehiclePropertyValue;
        try
        {
            switch (VehiclePropertyToSetIndex)
            {
                case eVehiclePropertyIndex.EngineType:
                    {
                        this.AllocateNewEngine(VehiclePropertyValue);
                        break;
                    }

                case eVehiclePropertyIndex.ModelName:
                    {
                        m_ModelName = VehiclePropertyValue.ToString();
                        break;
                    }

                case eVehiclePropertyIndex.WheelManufacturer:
                    {
                        m_WheelManufacturer = VehiclePropertyValue.ToString();
                        this.InitilizeWheels(m_NumOfWheels, Wheel.ePressureType.Car, m_WheelManufacturer);
                        break;
                    }

                case eVehiclePropertyIndex.Color:
                    {
                        m_Color = (eColor)ValidateEnumRanges(typeof(eColor), VehiclePropertyValue);
                        break;
                    }

                case eVehiclePropertyIndex.NumOfDoors:
                    {
                        m_NumOfDoors = (eNumOfDoors)ValidateEnumRanges(typeof(eNumOfDoors), VehiclePropertyValue);
                        break;
                    }
            }
        }
        catch (ArgumentException argumentException)
        {
            throw new ArgumentException("Invalid input: " + argumentException.Message);
        }
    }

    protected override void AllocateNewEngine(object i_VehiclePropertyValue)
    {
        Engine.eEngineType CurrentVehicleEngineType = (Engine.eEngineType)ValidateEnumRanges(typeof(Engine.eEngineType), i_VehiclePropertyValue);

        if (CurrentVehicleEngineType.Equals(Engine.eEngineType.Fuel))
        {
            this.Engine = new FuelEngine(FuelEngine.eEngineFuelType.Octan95, 41);
        }
        else if (CurrentVehicleEngineType.Equals(Engine.eEngineType.Electric))
        {
            this.Engine = new ElectricEngine(2.2f);
        }
    }
}
